package net.slenderloris.touchclient;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class MainActivity extends Activity {

	protected static final String TAG = MainActivity.class.getCanonicalName();

	private static final int ACTION_UP = 0x1;
	private static final int ACTION_DOWN = 0x2;
	private static final int ACTION_MOVE = 0x3;
	
	private OnTouchListener mTouchListener = new OnTouchListener() {
		
		@Override
		public boolean onTouch(View v, MotionEvent event) {

			int ai = event.getActionIndex();
			
			switch(event.getActionMasked()) {
			case MotionEvent.ACTION_DOWN:
			case MotionEvent.ACTION_POINTER_DOWN:
				sendEvent((byte) ACTION_DOWN,
						event.getEventTime(),
						event.getPointerId(ai),
						event.getX(ai),
						event.getY(ai));
				break;
			case MotionEvent.ACTION_UP:
			case MotionEvent.ACTION_POINTER_UP:
				sendEvent((byte) ACTION_UP,
						event.getEventTime(),
						event.getPointerId(ai),
						event.getX(ai),
						event.getY(ai));
				break;
			case MotionEvent.ACTION_MOVE:
				for(int i=0; i<event.getPointerCount(); i++) {
					sendEvent((byte) ACTION_MOVE,
							event.getEventTime(),
							event.getPointerId(i),
							event.getX(i),
							event.getY(i));
				}
				break;
			}
			
			return true;
		}
	};

	private BluetoothThread mNetThread;
	private long mBaseTime;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		View root = findViewById(R.id.root);
		root.setOnTouchListener(mTouchListener);
		mNetThread = new BluetoothThread();
		mBaseTime = SystemClock.uptimeMillis();
	}
	
	private static final int MAX_POINTERS = 20;
	
	private Point mLastXYs[] = new Point[MAX_POINTERS];

	protected void sendEvent(byte action, long eventTime, int pointerId, float fx, float fy) {
		
		if(pointerId>=MAX_POINTERS) {
			return;
		}
		
		int time = (int) (eventTime-mBaseTime);
		byte id = (byte) pointerId;
		short x = (short) fx;
		short y = (short) fy;

		if(action==ACTION_MOVE) {
			Point last = mLastXYs[pointerId];
			if(last!=null && last.x==x && last.y==y) {
				return;
			}
			else {
				if(last==null) {
					mLastXYs[pointerId] = new Point(x,y);
				}
				else {
					mLastXYs[pointerId].x = x;
					mLastXYs[pointerId].y = y;
				}
			}
			
		}
		
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(baos);
		try {
			dos.writeByte(action);
			dos.writeByte(id);
			dos.writeInt(time);
			dos.writeShort(x);
			dos.writeShort(y);
			mNetThread.write(baos.toByteArray());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				dos.close();
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}


	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}
